package com.ruoyi.common.utils.equipment;

import java.util.Arrays;

public class ConverterTool
{

	public static byte[] longToBytes(long src,int lsize,boolean byteOrder)
	{//转换long数值为字节数组，
		//src--需要转换的数值
		//size -- 需要返回的数组元素数
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		byte [] buf=new byte[8];
		int iIndex=0,i=0;

		if(byteOrder) {
			iIndex = 56;//高位在前，低位在后。
		}else {
			iIndex = 0;//低位在前，高位在后。
		}
		for( i=0; i < 8; i++) {
			buf[i] = (byte)(src>>iIndex);
			if(byteOrder) {
				iIndex -= 8;
			}else {
				iIndex += 8;
			}
		}
		//返回数组
		if(byteOrder){
			if(lsize>8){
				//需要返回的数组大于8字节，则创建一个指定维数的数组，并拷贝数据至新数组后8字节。
				byte [] tmp=new byte[lsize];
				System.arraycopy(buf,0,tmp,lsize-8,8);
				return  tmp;//只返回8字节。
			}else {
				return Arrays.copyOfRange(buf, 8 - lsize, (8 - lsize) + lsize);//高位在前，低位在后。从数组后面往前截取
			}
		}else{
			return Arrays.copyOf(buf, lsize);//低位在前，高位在后。
		}
	}

	public static long BytesTolong(byte[] src,boolean byteOrder)
	{//转换字节数组为数值，
		//src--需要转换的字节数组
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		int iIndex=0;
		long lValue=0;
		if(byteOrder){
			//只取8个字节,后8个
			if(src.length>8) {
				src = Arrays.copyOfRange(src, src.length - 8, src.length);
			}else{
				//不足8字节，创建一个8字节的数组，并把源数组内容拷贝只新数组后8字节。
				byte [] tmp=new byte[8];
				System.arraycopy(src,0,tmp,8-src.length,src.length);
				src=Arrays.copyOf(tmp,8);
			}
			iIndex=0;//高位在前，低位在后。
		}else{
			//只取8个字节,前8个
			src=Arrays.copyOf(src,8);
			iIndex=7;//低位在前，高位在后。
		}
		for(int i=0; i < 8; i++){
			lValue += uByte(src[iIndex]); //取字节的无符号整形数值
			if(i<7) {
				lValue = lValue << 8;//移位
			}
			if(byteOrder) {
				iIndex += 1;
			}else {
				iIndex -= 1;
			}
		}
		return lValue;
	}

	public static int uByte(byte byte0){
		return byte0 & 0xff;
	}
	public static long uInt(int i){
		return Long.parseLong(Integer.toHexString(i), 16);
	}
	public static byte [] BytetoBits(byte src,boolean byteOrder){
		//转换字节为8个bit数组，
		//src--需要转换的字节
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		int iData=uByte(src);
		byte[] dstBits=new byte[8];
		for(int i=0; i < 8; i++){
			if(byteOrder) {
				dstBits[7 - i] = (byte) (iData % 2);
			}else {
				dstBits[i] = (byte) (iData % 2);
				iData = iData / 2;
			}
		}
		return dstBits;
	}
	//功能:Bits 到 Byte 的转换,
	public static byte BitstoByte(byte srcBits[],boolean byteOrder){
		//转换8个bit数组为一个字节(Byte)
		//srcBits--需要转换的字节
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		int i=0,iIndex=0;
		int dst=0;

		//初始化数组
		if(byteOrder){
			//只取8个字节,后8个
			if(srcBits.length>8) {
				srcBits = Arrays.copyOfRange(srcBits, srcBits.length - 8, srcBits.length);
			}else{
				//不足8字节，创建一个8字节的数组，并把源数组内容拷贝只新数组后8字节。
				byte [] tmp=new byte[8];
				System.arraycopy(srcBits,0,tmp,8-srcBits.length,srcBits.length);
				srcBits=Arrays.copyOf(tmp,8);
			}
			iIndex=0;//高位在前，低位在后。
		}else{
			//只取8个字节,前8个
			srcBits=Arrays.copyOf(srcBits,8);
			iIndex=7;//低位在前，高位在后。
		}
		//开始抓换
		for(i=0; i < 8; i++){
			dst += srcBits[iIndex];
			if(i<7) {
				dst = dst << 1;//移位
			}
			if(byteOrder){
				iIndex++;
			}else {
				iIndex--;
			}
		}
		return (byte)dst;
	}

	//功能:Byte 到 Bits 的转换,
	//参数:待变换数据,处理后结果存放缓冲区指针,Bits缓冲区大小
	public static void BytestoBits(byte [] srcBytes, byte [] dstBits, int sizeBits){
		BytestoBits(srcBytes,dstBits,sizeBits,true);
	}
	public static void BytestoBits(byte [] srcBytes, byte [] dstBits, int sizeBits,boolean byteOrder){
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		int iData,lIndex=0;
		byte buf[];
		//初始化数组
		Arrays.fill(dstBits,(byte)0);
		for(int i=0; i < srcBytes.length; i++){
			buf=BytetoBits(srcBytes[i],byteOrder);
			if(lIndex+8<=sizeBits) {
				System.arraycopy(buf, 0, dstBits, lIndex, 8);
			}else {
				System.arraycopy(buf, 0, dstBits, lIndex, sizeBits - lIndex);
				lIndex += 8;
			}
			if(lIndex >= sizeBits) {
				break;
			}
		}
	}

	//功能:Bits 到 Byte 的转换,
	//参数:存储转换后的Byte数组,准备转换为byte的bit数组,Bits缓冲区大小
	public static void BitsToBytes(byte [] dstBytes, byte [] srcBits, int sizeBits){
		BitsToBytes(dstBytes,srcBits,sizeBits,true);
	}
	public static void BitsToBytes(byte [] dstBytes, byte [] srcBits, int sizeBits,boolean byteOrder){
		//byteOrder -- 数组字节顺序：
		//		true  表示：高位在前，低位在后。
		//		false 表示：低位在前，高位在后。
		int i=0,lIndex=0;
		//初始化数组
		Arrays.fill(dstBytes,(byte)0);
		byte bits[]=new byte[8];
		//开始转换
		for(i=0; i < sizeBits; i+=8){
			System.arraycopy(srcBits,i,bits,0,8);
			dstBytes[lIndex++]=BitstoByte(bits,byteOrder);
		}
	}
	//功能:Byte到Hex的转换
	//参数:需要转换的字节数组，转换的长度
	public static String Byte2Hex(byte[] b){
		char[] sHexbuf=new char[b.length * 2];
		int lIndex=0;
		int iData;

		char[] digits =  {'0' , '1' , '2' , '3' , '4' , '5' ,'6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' };
		try{
			for(int i=0;i<b.length;i++){
				iData= uByte(b[i]);//取字节的无符号整形数值
				sHexbuf[lIndex++] = digits[iData / 16];
				sHexbuf[lIndex++] = digits[iData % 16];
			}
			return new String(sHexbuf).toUpperCase();
		}
		catch(Exception e){
			return new String();
		}
	}

	public static byte[] Hex2Byte(String hexString){
		/*BigInteger big=new BigInteger(hexString,16);
		return big.toByteArray();*/
		int i,iIndex=0,iData;
		//确定字符串长度必须是2的倍数
		if( (hexString.length() % 2) ==1 ){
			hexString="0"+hexString;
		}
		//生成转换值列表
		byte [] digits =new byte[128];
		byte [] tmp;
		tmp  = "0123456789abcdef".getBytes();
		for(i=0;i<tmp.length;i++) {
			digits[tmp[i]] = (byte) i;
			tmp = "ABCDEF".getBytes();
		}
		for(i=0;i<tmp.length;i++) {
			digits[tmp[i]] = (byte) (i + 10);
		}
		//生成缓存
		byte[] buf=new byte[hexString.length() / 2 ];
		byte[] sbuf=hexString.getBytes();
		//开始转换
		for(i=0;i<sbuf.length;i++){
			iData=digits[sbuf[i++]]*16;
			iData=iData+digits[sbuf[i]];
			buf[iIndex]=(byte)iData;
			iIndex++;
		}
		return buf;
	}

	//显示字节数组中的内容
	public static String BytesToString(byte bBytes[]){
		String sOut="";
		int ret;
		for (int i =0 ;i<bBytes.length;i++){
			ret=uByte(bBytes[i]);//取字节的无符号整形数值
			if(i!=bBytes.length-1) {
				sOut = sOut + ret + ",";
			}else {
				sOut = sOut + ret;
			}
		}
		return sOut;
	}

}
